﻿using ModernChannel.Data;
using ModernChannel.Model.Interface;
using ModernChannel.Model.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Common.Util;
using ModernChannel.Configuration;
using Common.Contract.Customer.Identifier;

namespace ModernChannel.Provider
{
    public class ShopInfoProvider : GenericProvider, IShopInfoProvider
    {
        public List<ShopInf> SearchShopInf(out int totalRecord, DateTime? fromDate = null, DateTime? toDate = null,
            string shopCode = null, string shopName = null, string address = null, string billToCode = null, string regionId = null,
            string cellNo1 = null, string distCode = null, string provinceCode = null, string customerCode = null, string ownerName = null,
            string ownerEmail = null, string areaCode = null, string shopType = null, bool? active = null, int pagesize = 0, int pageindex = 0, bool? includeArea = null)
        {
            var querry = repository.GetQuery<ShopInf>();
            if (!string.IsNullOrWhiteSpace(shopCode))
            {
                querry = querry.Where(x => x.ShopCode.ToUpper() == shopCode.ToUpper());
            }

            if (!string.IsNullOrWhiteSpace(shopName))
            {
                querry = querry.Where(x => x.ShopName.ToUpper().Contains(shopName.ToUpper()));
            }

            if (!string.IsNullOrWhiteSpace(address))
            {
                querry = querry.Where(x => x.Address.ToUpper().Contains(address.ToUpper()));
            }

            if (!string.IsNullOrWhiteSpace(billToCode))
            {
                querry = querry.Where(x => x.BilltoCode.ToUpper() == billToCode.ToUpper());
            }

            if (!string.IsNullOrWhiteSpace(regionId) && regionId != SystemConfiguration.ALL_REGION_CODE)
            {
                querry = querry.Where(x => x.RegId.ToUpper() == regionId.ToUpper());
            }

            if (!string.IsNullOrWhiteSpace(cellNo1))
            {
                querry = querry.Where(x => x.CellNo1.ToUpper() == cellNo1.ToUpper());
            }

            if (!string.IsNullOrWhiteSpace(distCode))
            {
                querry = querry.Where(x => x.DistCode.ToUpper() == distCode.ToUpper());
            }

            if (!string.IsNullOrWhiteSpace(provinceCode))
            {
                querry = querry.Where(x => x.ProvinceCode.ToUpper() == provinceCode.ToUpper());
            }

            if (!string.IsNullOrWhiteSpace(customerCode))
            {
                querry = querry.Where(x => x.CustomerCode.ToUpper() == customerCode.ToUpper());
            }

            if (!string.IsNullOrWhiteSpace(ownerName))
            {
                querry = querry.Where(x => x.OwnerName.ToUpper().Contains(ownerName.ToUpper()));
            }

            if (!string.IsNullOrWhiteSpace(ownerEmail))
            {
                querry = querry.Where(x => x.OwnerEmail.ToUpper().Contains(ownerEmail.ToUpper()));
            }

            if (!string.IsNullOrWhiteSpace(areaCode))
            {
                querry = querry.Where(x => x.AreaCode.ToUpper() == areaCode.ToUpper());
            }

            if (!string.IsNullOrWhiteSpace(shopType))
            {
                querry = querry.Where(x => x.ShopType.ToUpper() == shopType.ToUpper());
            }

            if (fromDate.HasValue)
            {
                var fromdate = fromDate.Value.Date;
                querry = querry.Where(x => x.CreateDate != null || x.CreateDate >= fromdate);
            }

            if (toDate.HasValue)
            {
                var todate = toDate.Value.Date.AddDays(1);
                querry = querry.Where(x => x.CreateDate != null || x.CreateDate < todate);
            }

            if (active.HasValue)
            {
                var userflag = active.Value.ToBooleanString();
                querry = querry.Where(x => x.UseFlag.ToUpper() == userflag);
            }
            querry = querry.OrderBy(x => x.ShopCode);
            totalRecord = querry.Count();
            if (pagesize > 0 && pageindex >= 0)
            {
                querry = querry.Skip(pageindex * pagesize).Take(pagesize);
            }
            var result = querry.ToList();
            if (includeArea == true)
            {
                var dictRegion = repository.GetAll<Region>().ToDictionary(x => x.Id);
                var dictProvince = repository.GetAll<Province>().ToDictionary(x => x.Id.ToString());
                var dictDistrict = repository.GetAll<District>().ToDictionary(x => x.Id.ToString());

                result = result.Select((x) =>
                {
                    if (!x.RegId.IsNullOrWhiteSpace() && dictRegion.ContainsKey(x.RegId)) x.Region = dictRegion[x.RegId];
                    if (!x.ProvinceCode.IsNullOrWhiteSpace() && dictProvince.ContainsKey(x.ProvinceCode)) x.Province = dictProvince[x.ProvinceCode];
                    if (!x.DistCode.IsNullOrWhiteSpace() && dictDistrict.ContainsKey(x.DistCode)) x.District = dictDistrict[x.DistCode];
                    return x;
                }).ToList();
            }

            return result;
        }


        public List<ShopInf> SearchShopInf(out int totalRecord, string searchText, int pagesize = 0, int pageindex = 0, bool? includeArea = null)
        {

            var querry = repository.GetQuery<ShopInf>();
            if (!string.IsNullOrWhiteSpace(searchText))
            {
                querry = querry.Where(x => x.ShopCode.ToUpper() == searchText.ToUpper() ||
                                           x.ShopName.ToUpper().Contains(searchText.ToUpper()) ||
                                           x.Address.ToUpper().Contains(searchText.ToUpper()) ||
                                           x.BilltoCode.ToUpper() == searchText.ToUpper() ||
                                           x.CellNo1.ToUpper() == searchText.ToUpper() ||
                                           x.CellNo2.ToUpper() == searchText.ToUpper() ||
                                           x.CustomerCode.ToUpper() == searchText.ToUpper() ||
                                           x.OwnerName.ToUpper() == searchText.ToUpper() ||
                                           x.OwnerEmail.ToUpper() == searchText.ToUpper()
                                           );

            }

            querry = querry.OrderBy(x => x.ShopCode);
            totalRecord = querry.Count();
            if (pagesize > 0 && pageindex >= 0)
            {
                querry = querry.Skip(pageindex * pagesize).Take(pagesize);
            }
            var result = querry.ToList();
            if (includeArea == true)
            {
                var dictRegion = repository.GetAll<Region>().ToDictionary(x => x.Id);
                var dictProvince = repository.GetAll<Province>().ToDictionary(x => x.Id.ToString());
                var dictDistrict = repository.GetAll<District>().ToDictionary(x => x.Id.ToString());

                result = result.Select((x) =>
                {
                    if (dictRegion.ContainsKey(x.RegId)) x.Region = dictRegion[x.RegId];
                    if (dictProvince.ContainsKey(x.DistCode)) x.Province = dictProvince[x.DistCode];
                    if (dictDistrict.ContainsKey(x.DistCode)) x.District = dictDistrict[x.DistCode];
                    return x;
                }).ToList();
            }

            return result;
        }

        public ShopInf RetrieveShopInf(string shopcode)
        {
            shopcode = (shopcode ?? string.Empty).ToUpper();
            return repository.FindOne<ShopInf>(x => x.ShopCode.ToUpper() == shopcode);
        }

        public bool Update(ShopInf shop)
        {
            try
            {
                var shopCode = shop.ShopCode ?? string.Empty;
                var shopChecked = repository.FindOne<ShopInf>(x => x.ShopCode.ToUpper() == shopCode.ToUpper());
                if (shopChecked == null) return false;
                shopChecked.BilltoCode = shop.BilltoCode;
                shopChecked.ShopName = shop.ShopName;
                shopChecked.Address = shop.Address;
                shopChecked.AreaCode = shop.AreaCode;
                shopChecked.CellNo1 = shop.CellNo1;
                shopChecked.CellNo2 = shop.CellNo2;
                shopChecked.Channel = shop.Channel;
                shopChecked.RegId = shop.RegId;
                shopChecked.DistCode =shop.DistCode;
                shopChecked.ProvinceCode = shop.ProvinceCode;
                shopChecked.IsdnNo = shop.IsdnNo;
                shopChecked.CustomerCode = shop.CustomerCode;
                shopChecked.OwnerName = shop.OwnerName;
                shopChecked.OwnerEmail = shop.OwnerEmail;
                shopChecked.ShopType = shop.ShopType;
                shopChecked.Address = shop.Address;
                if (shop.SoTransferDate.HasValue) shopChecked.SoTransferDate = shop.SoTransferDate;
                if (!shop.SoTransferFlag.IsNullOrWhiteSpace()) shopChecked.SoTransferFlag = shop.SoTransferFlag;
                if (!shop.UseFlag.IsNullOrWhiteSpace()) shopChecked.UseFlag = shop.UseFlag;
                if (!shop.UpdateUser.IsNullOrWhiteSpace()) shopChecked.UpdateUser = shop.UpdateUser;
                if (shop.CreateDate.HasValue) shopChecked.CreateDate = shop.CreateDate;
                if (!shop.CreateUser.IsNullOrWhiteSpace()) shopChecked.CreateUser = shop.CreateUser;
                if (shop.UpdateDate.HasValue) shopChecked.UpdateDate = shop.UpdateDate;

                shopChecked.ShopCode = shop.ShopCode;
                shopChecked.ShopName = shop.ShopName;
                repository.UnitOfWork.SaveChanges();
                return true;

            }
            catch
            {
                return false;
            }
        }

        public bool Add(ShopInf shop)
        {
            try
            {
                repository.ShopInf.Add(shop);
                repository.UnitOfWork.SaveChanges();
                return true;
            }
            catch
            {
                return false;
            }
        }

        public bool Delete(string shopcode)
        {
            try
            {
                var appKey = (shopcode ?? string.Empty).ToUpper();
                repository.Delete<ShopInf>(x => x.ShopCode.ToUpper() == shopcode);
                repository.UnitOfWork.SaveChanges();
                return true;
            }
            catch
            {
                return false;
            }
        }
    }
}

